feat(auth): OAuth login with automatic ingestion token provisioning#82
Draft
cpoepke wants to merge 3 commits into
Draft
feat(auth): OAuth login with automatic ingestion token provisioning#82cpoepke wants to merge 3 commits into
cpoepke wants to merge 3 commits into
Conversation
Adds a browser-based sign-in flow so users can authenticate the Dash0 Claude Code plugin once and have it emit telemetry on their behalf. - /dash0-agent-plugin:login slash command runs OAuth 2.0 + PKCE against Clerk (Dash0's identity provider). Discovery via RFC 8414 metadata, PKCE S256. Defaults to https://clerk.dash0.com; auto-selects the dev tenant when DASH0_OTLP_URL points at a .dash0-dev.com host. - Credentials are persisted to the OS user-config dir (mode 0600): ~/Library/Application Support/dash0/credentials.json (macOS) $XDG_CONFIG_HOME/dash0/credentials.json (Linux) %AppData%\dash0\credentials.json (Windows) - After OAuth, the plugin uses the issued Clerk JWT to mint a long-lived auth_* token via CPA POST /public/ui/organization/auth-tokens. Falls back to the short-lived OAuth access_token when mint fails (e.g. dev envs without admin role). - Refresh-token rotation: offline_access scope yields a refresh token; SessionStart hook auto-refreshes on 401, re-mints, persists, retries CheckConnectivity, and reports the rotated state to the user. - SessionStart printHookResponse always emits a status line: - dash0: telemetry is not active (no OTLP_URL) - dash0: not authenticated (no token) - dash0: auth token rejected (401 after refresh) - dash0: connected as <org-id> (valid) The "needs login" branches put a Skill-tool nudge into additionalContext so Claude proactively invokes the slash command before continuing with the user's request. - Per-user OAuth client registration caches client_id + the bound loopback port in clients.json so repeat logins reuse the same redirect_uri (Dash0 / Clerk enforce exact match). - New userConfig entries: AUTH_URL, OAUTH_CLIENT_ID (plus env-var fallbacks DASH0_AUTH_URL, DASH0_OAUTH_CLIENT_ID). - Drops the original region selector (us / eu / dev) and the DASH0_REGION env var — the URL-only model matches Dash0's real topology (Clerk for OAuth, CPA for mint, regional API for ingest). Credentials now carry AuthURL, ClientID, RefreshToken instead of Region/APIBase. Clients map keyed by AuthURL. - CI adds an auth-e2e job that runs the mocked flow without an ANTHROPIC_API_KEY secret (works for fork PRs). - 14 e2e scenarios + 160 unit tests cover discover/register/exchange/ mint/refresh paths against an in-process mock Clerk-shaped server.
Pure formatting (struct-tag alignment). No behavior changes.
c059ddd to
1755279
Compare
Replace the Clerk-specific MintMachineToken path (POST /public/ui/organization/auth-tokens) with a call to PUT /api/auth-tokens/claude-code-plugin — the new idempotent get-or-create endpoint added to the CPA. This removes the admin-only constraint: any org member with allowMembersClaudeCodeAccess=true can now log in and get a permanent ingestion token. Changes: - Add ProvisionIngestionToken() calling PUT /api/auth-tokens/claude-code-plugin - Add IngestionToken field to Credentials; OTLP hook prefers it over AuthToken - Remove MintMachineToken, ErrNotAdmin, deriveCPAURL (all obsolete) - Remove Clerk-specific ClientID/Scope login options and OAUTH_CLIENT_ID plugin config - RefreshCredentials no longer attempts to re-mint; ingestion token persists across refreshes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
TL;DR
/dash0-agent-plugin:loginto authenticate once; the plugin provisions a permanentauth_*ingestion token automatically, so telemetry works without pasting tokens manually.PUT /api/auth-tokens/claude-code-plugincall (idempotent get-or-create). The short-liveddash0_at_*OAuth token is kept only for token refresh; the ingestion token is what OTLP requests actually use.allowMembersClaudeCodeAccessorg setting.Overview
allowMembersClaudeCodeAccessorg setting (admin-configurable)Feature:
/dash0-agent-plugin:loginslash commandDetails
What & Why:
/plugin Configure. This PR replaces that with a one-command login flow.Implementation:
https://api.<region>.aws.dash0.com(the Dash0 regional API). Discovery via RFC 8414 metadata. Dynamic Client Registration (RFC 7591) for loopback redirect URIs.PUT /api/auth-tokens/claude-code-pluginwith the OAuth access token. This is an idempotent get-or-create — repeated logins return the same token.auth_*ingestion token is persisted asIngestionTokenincredentials.json. The OTLP hook prefers it over the OAuth access token so OTLP requests bypass the OAuth rotation cycle entirely.RefreshCredentialsupdates onlyAuthToken;IngestionTokenis never overwritten on refresh (it doesn't expire).client_idand the bound loopback port inclients.jsonso repeated logins reuse the sameredirect_uri.SessionStarthook emitsdash0: connected as <org>on success. The "needs login" branch puts a Skill-tool nudge intoadditionalContextso Claude proactively prompts the user to run the command.~/Library/Application Support/dash0/credentials.json(macOS),$XDG_CONFIG_HOME/dash0/credentials.json(Linux),%AppData%\dash0\credentials.json(Windows), mode0600.Feature: Ingestion token provisioning replaces manual token paste
Details
What & Why:
MintMachineTokenviaPOST /public/ui/organization/auth-tokens) required admin role and was tied to Clerk JWTs. The newProvisionIngestionTokenuses the standard Dash0 OAuth access token and works for any org member once the admin enablesallowMembersClaudeCodeAccess.Implementation:
MintMachineToken,ErrNotAdmin, andderiveCPAURLare deleted — they are no longer used.ProvisionIngestionTokencallsPUT /api/auth-tokens/claude-code-plugin(a new endpoint in dash0#13604). The CPA enforces theallowMembersClaudeCodeAccessorg setting for non-admin callers.OAUTH_CLIENT_IDplugin config option removed (Clerk-specific, no longer needed).AUTH_URLdescription updated to reflect the regional API URL pattern.Checklist
Details
I have created a Chromatic build and reviewed the results.(no UI changes in this repo)If code is behind a feature flag, I've ensured the existing code is not broken.(not flagged)